# -*- coding: utf-8 -*-
#!/usr/bin/python

#------------------------------------------------------------------------

## @package     main
## \brief       initialisation de l'application, gestion des entrées/sorties et actualisation.
## \author      Eric Maisel
## \note        edited by Pierrick Troadec et Kawtar Hssain
## \date        28/12/11
## \version     1.2
## \copyright   license BSD

#------------------------------------------------------------------------


#    Importations
#  -----------------

import pyglet
from pyglet.gl import *

import math
import sys

import camera
import scene0 as scene
import piece as _piece
import prof as _prof
import horloge as _horloge
import jukebox as _jukebox
import question
import primitives as prims

from constante import *


fsock = open('error.log', 'w')                             
sys.stderr = fsock      

# Variables globales
#  -----------------

try:
	## Variable de configuration materiel ( carte graphique)
	config = Config(sample_buffer=1, samples=4, \
	  depth_size=16, double_buffer=True)
	## Variable contenant l'ecran si la configuration materielle a reussi
	window = pyglet.window.Window(resizable=True, config=config)
except:
	## et une autre si echec si echec (cf code)
	window = pyglet.window.Window(resizable=True)

## Variable de gestion du temps
horloge=0.0





## Variable globale de scrutation de la touche "avant"
Av=False
## Variable globale de scrutation de la touche "arriere"
Ar=False
## Variable globale de scrutation de la touche "gauche"
Ga=False
## Variable globale de scrutation de la touche "droite"
Dr=False
## Variable globale de scrutation de la touche "A"
A = False
## Variable globale de scrutation de la touche " de reponse"
key = None


#   Fonctions
#  -----------------

##Fonction qui prépare le contexte opengl à l'affichage de texte
def prepare_text():
	
	glMatrixMode(GL_PROJECTION)
	glPushMatrix() # sauvegarde de la matrice de projection 3D
	glLoadIdentity() # chargement de la matrice identite
	gluOrtho2D(0,800,0,600) # Changement de la matrice de projection (Passage en 2D)
	glMatrixMode(GL_MODELVIEW)

##Fonction qui signale à opengl que l'on arrête d'afficher du texte 
def after_text():

	glMatrixMode(GL_PROJECTION)
	glPopMatrix() # re-chargement de la matrice sauvegardée dans prepare_text()
	glMatrixMode(GL_MODELVIEW)


##Initialisation:
#           - de l'affichage openGl
#           - du monde 3D
#           - récuperation des différents éléments
def setup():

	global batiment, listeProf, aventurier, listeCouloir, temps, jukebox1
	
	
	glEnable(GL_DEPTH_TEST)

	glEnable(GL_TEXTURE_2D)
	glAlphaFunc(GL_GREATER,0.4)
	glEnable(GL_ALPHA_TEST)



	## Chargement des textures
	listeProf,batiment, aventurier, listeCouloir =scene.initScene()
	temps = _horloge.creerHorloge()
	jukebox1 = _jukebox.creerJukebox(SINGLE)
	jukebox2 = _jukebox.creerJukebox(LOOP)
	_jukebox.changerSon(jukebox2, ambiance)
	_jukebox.play(jukebox2)
	

	

@window.event
## Fonction gérant la modification de l'écran:
#   
## @param width   : largeur de l'écran
## @param height  : longueur de l'écran
def on_resize(width, height):

	# Override the default on_resize handler to create a 3D projection
	glViewport(0, 0, width, height)
	glMatrixMode(GL_PROJECTION)
	glLoadIdentity()
	gluPerspective(60.0, width / float(height), .1, 1000.)
	glMatrixMode(GL_MODELVIEW)
	return pyglet.event.EVENT_HANDLED


@window.event
## Affichage du monde
def on_draw():

	global textureSol, texturePanneau, batiment, key, aventurier, temps, jukebox1

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

	# Placement de la caméra
	oeil, pointVise, verticale = camera.parametresCamera()

	ex,ey,ez = oeil
	ax, ay, az = pointVise
	

	_temps = pyglet.text.Label(temps["affichage"],\
					font_name='Arial',\
					font_size=25,\
					color = (0, 0, 0, 255),\
					bold = True,\
					x = 0, y = 550)
					
	score = pyglet.text.Label("Score: "+ str(aventurier["score"]),\
					font_name='Arial',\
					font_size=25,\
					color = (0, 0, 0, 255),\
					bold = True,\
					x = 600, y = 550)
	
	
	# Placement de la caméra virtuelle
	glLoadIdentity()
	prepare_text()
	
	if (temps["fin"] and aventurier["gagnant"]) or aventurier["score"] == SCORE_MAX:
		prims.afficherImage(position=(0,0,0), dimension = (800,600), texture = winner, rep=1)
		
	elif temps["fin"] and not aventurier["gagnant"]:
		prims.afficherImage(position=(0,0,0), dimension = (800,600), texture = loser, rep=1)
		
	stop = question.afficherQuestion(ex,ez, batiment, key, aventurier, jukebox1)
	score.draw()
	_temps.draw()
	after_text()
	gluLookAt( ex,ey,ez,  ax, ay, az,  0.0,1.0,0.0)
	scene.afficherScene()
	
		
		
	


	
@window.event
## Scrutation des évènements clavier (touche enfonce):
## @param symbol   : touche appuye
## @param modifiers : modifieur de touche
def on_key_press(symbol,modifiers):
	


	global Av
	global Ar
	global Ga
	global Dr 
	
	global A, key
		
	

	if symbol == pyglet.window.key.LEFT or symbol == pyglet.window.key.Q  : # Fleche gauche 
		#camera.rotationCamera(-2.0)
		Ga=True
	elif symbol == pyglet.window.key.RIGHT or symbol == pyglet.window.key.D : # Fleche droite
		#camera.rotationCamera(2.0)
		Dr=True
	elif (symbol == pyglet.window.key.UP or symbol == pyglet.window.key.Z) : # Fleche haut
		#camera.deplacementCamera(0.5)
		Av=True
	elif symbol == pyglet.window.key.DOWN or symbol == pyglet.window.key.S: # fleche bas
		#camera.deplacementCamera(-0.5)
		Ar=True
	elif symbol == pyglet.window.key.P:#test de fermeture des portes
		pass
			
	elif symbol == pyglet.window.key.A:
		A = True
		key == "a"
		
	elif symbol == pyglet.window.key.F:
		key = "f"
		
	elif symbol == pyglet.window.key.NUM_1 or symbol == pyglet.window.key.E:
		key = 1
	elif symbol == pyglet.window.key.NUM_2 or symbol == pyglet.window.key.R:
		key = 2
	elif symbol == pyglet.window.key.NUM_3 or symbol == pyglet.window.key.T:
		key = 3
		

@window.event
## Scrutation des évenèments clavier (touche relache):
#   
## @param symbol   : touche relâchée
## @param modifiers : modifieur de touche
def on_key_release(symbol,modifiers):

	
	global Av
	global Ar
	global Ga
	global Dr   
		
	global A
	
	
	if symbol == pyglet.window.key.LEFT or symbol == pyglet.window.key.Q  : # Fleche gauche 
		#camera.rotationCamera(-2.0)
		Ga=False
	elif symbol == pyglet.window.key.RIGHT or symbol == pyglet.window.key.D : 
		#camera.rotationCamera(2.0)
		Dr=False
	elif symbol == pyglet.window.key.UP or symbol == pyglet.window.key.Z : # Fleche haut
		#camera.deplacementCamera(0.5)
		Av=False
	elif symbol == pyglet.window.key.DOWN or symbol == pyglet.window.key.S: # fleche bas
		#camera.deplacementCamera(-0.5)
		Ar=False
	elif symbol == pyglet.window.key.A:
		A = False



@window.event
## Scrutation des évènements clavier (touche enfonce):
#   
## @param x          : position absolue en abscisse de la souris.
## @param y          : position absolue en ordonnees de la souris.
## @param dx         : déplacement relatif en abscisse de la souris.
## @param dy         : déplacement relatif en ordonnees de la souris.
## @param boutons    : touche appuyée
## @param modifiers   : modifieur de touche

def on_mouse_drag(x,y,dx,dy,boutons,modifiers):


	camera.rotationCamera(dx)
	camera.rotationCameraY(dy)
	for prof in listeProf:
		_prof.tourner(prof, dx)

## Mise à jour de l'environnement et intéraction avec les autres personnages :
## @param dt        : intervalle de temps depuis la dernière mise à jour
def update(dt):


	global horloge
	global Av, Ar, Ga, Dr
	global batiment, listeProf, listeCouloir, aventurier, jukebox1
	
	global A, stop, temps
	
	horloge = horloge + dt
	positionCamera = camera.positionOeil
	
	
	if Av :
		camera.deplacementCamera(0.5, batiment, aventurier, listeCouloir) 
	if Ar :
		camera.deplacementCamera(-0.5, batiment, aventurier, listeCouloir)
	if Ga :
		camera.rotationCamera(-5.0)
		for prof in listeProf:
			_prof.tourner(prof, -5.0)
	if Dr :
		camera.rotationCamera(5.0)
		for prof in listeProf:
			_prof.tourner(prof, 5.0)
	
	_prof.collisionProf(positionCamera[0], positionCamera[2], batiment, A)
	_horloge.actualiser(temps)
	_jukebox.play(jukebox1)
	
	
	if (temps["fin"] and aventurier["score"] >= SCORE_MAX/2) or aventurier["score"] == SCORE_MAX:
		aventurier["gagnant"] = True
		aventurier["bloque"] =  True
	elif temps["fin"] and aventurier["score"] < SCORE_MAX/2: 
		aventurier["bloque"] =  True
		
		
		

	

if __name__ == "__main__":
	
	print "Hello World"
	setup()

	# La fonction update sera appelée toutes les 30èmes de seconde.
	pyglet.clock.schedule_interval(update, 1.0/30.0)


	pyglet.app.run()
